From fabc0d6c64f6fd040d6c14b3ac0b34f8d7be7ea6 Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Tue, 16 Sep 2025 10:23:43 -0700 Subject: [PATCH 1/5] Update deps --- go.mod | 6 +++--- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ea1afa724..2d6bcd8d5 100644 --- a/go.mod +++ b/go.mod @@ -22,8 +22,8 @@ require ( github.com/onflow/flow-emulator v1.7.0 github.com/onflow/flow-evm-gateway v1.3.0 github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 - github.com/onflow/flow-go-sdk v1.8.1 - github.com/onflow/flowkit/v2 v2.5.0 + github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f + github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87 github.com/onflowser/flowser/v3 v3.2.1-0.20240131200229-7d4d22715f48 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/errors v0.9.1 @@ -291,7 +291,7 @@ require ( google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect - google.golang.org/protobuf v1.36.7 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/go.sum b/go.sum index 75a0d5072..09a1b91ff 100644 --- a/go.sum +++ b/go.sum @@ -803,6 +803,8 @@ github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 h1: github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9/go.mod h1:VkvpX4p4imUpPR+FhL0Qw7Qx32zQ/QOQRz2Vl2uu50Y= github.com/onflow/flow-go-sdk v1.8.1 h1:BPp7p10RrpOdezQ3RJ+nheOqpalHlTB9bRocVkLsGNU= github.com/onflow/flow-go-sdk v1.8.1/go.mod h1:w6bxCznDhJJCDybn1jCUAz3rEO4/7XY9EgWRFrj0zoo= +github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f h1:7l/WGE02V07jXveC0zjYCjHE651SeSXd1/6VVoNds5Q= +github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f/go.mod h1:Gc09IwcvwaW4kqZ9xTaC0KahRxWApGeEMnWVnW8ZNPA= github.com/onflow/flow-nft/lib/go/contracts v1.2.4 h1:gWJgSSgIGo0qWOqr90+khQ69VoYF9vNlqzF+Yh6YYy4= github.com/onflow/flow-nft/lib/go/contracts v1.2.4/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= @@ -811,6 +813,8 @@ github.com/onflow/flow/protobuf/go/flow v0.4.12 h1:nMJHVuz2iRQnzEwvmruCaMrQvm/df github.com/onflow/flow/protobuf/go/flow v0.4.12/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= github.com/onflow/flowkit/v2 v2.5.0 h1:Y5eFuFHem8a4gNaZl+47Jr7qyBFkU0X+opUVUD72CcE= github.com/onflow/flowkit/v2 v2.5.0/go.mod h1:wfWK0O8VxdCbAREo1Snnagt1l9GuqFdmyAQXeymzpiY= +github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87 h1:qQFjm2aLCn7mtJuCfXOmn6D/502foT+SYwtL1bMT0Nc= +github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87/go.mod h1:lwN9h5GKD7p3GhXl4QqM0Ddez/0Ad3gWb16YPoOZ6iI= github.com/onflow/go-ethereum v1.15.10 h1:blZBeOLJDOVWqKuhkkMh6S2PKQAJvdgbvOL9ZNggFcU= github.com/onflow/go-ethereum v1.15.10/go.mod h1:t2nZJtwruVjA5u5yEK8InFzjImFLHrF7ak2bw3E4LDM= github.com/onflow/nft-storefront/lib/go/contracts v1.0.0 h1:sxyWLqGm/p4EKT6DUlQESDG1ZNMN9GjPCm1gTq7NGfc= @@ -1463,6 +1467,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 1a2482ef20c2667e27bf22df14c511463210a37d Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Tue, 16 Sep 2025 16:54:56 -0700 Subject: [PATCH 2/5] Add extension data to displays, and include in convert --- go.mod | 6 ++--- go.sum | 34 +++++++++++---------------- internal/prompt/prompt.go | 22 ++++++++++++----- internal/transactions/transactions.go | 6 +++++ 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index 2d6bcd8d5..e9f106144 100644 --- a/go.mod +++ b/go.mod @@ -22,8 +22,8 @@ require ( github.com/onflow/flow-emulator v1.7.0 github.com/onflow/flow-evm-gateway v1.3.0 github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 - github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f - github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87 + github.com/onflow/flow-go-sdk v1.8.2 + github.com/onflow/flowkit/v2 v2.5.1 github.com/onflowser/flowser/v3 v3.2.1-0.20240131200229-7d4d22715f48 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/errors v0.9.1 @@ -291,7 +291,7 @@ require ( google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/go.sum b/go.sum index 09a1b91ff..a224368bb 100644 --- a/go.sum +++ b/go.sum @@ -72,20 +72,20 @@ github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8= -github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= +github.com/aws/aws-sdk-go-v2 v1.39.0 h1:xm5WV/2L4emMRmMjHFykqiA4M/ra0DJVSWUkDyBjbg4= +github.com/aws/aws-sdk-go-v2 v1.39.0/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1 h1:VGkV9KmhGqOQWnHyi4gLG98kE6OecT42fdrCGFWxJsc= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.1/go.mod h1:PLlnMiki//sGnCJiW+aVpvP/C8Kcm8mEj/IVm9+9qk4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 h1:6+lZi2JeGKtCraAj1rpoZfKqnQ9SptseRZioejfUOLM= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4 h1:ueB2Te0NacDMnaC+68za9jLwkjzxGWm0KB5HTUHjLTI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4/go.mod h1:nLEfLnVMmLvyIG58/6gsSA03F1voKGaCfHV7+lR8S7s= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7 h1:mLgc5QIgOy26qyh5bvW+nDoAppxgn3J2WV3m9ewq7+8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.7/go.mod h1:wXb/eQnqt8mDQIQTTmcw58B5mYGxzLGZGK8PWNFZ0BA= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0/go.mod h1:LKb3cKNQIMh+itGnEpKGcnL/6OIjPZqrtYah1w5f+3o= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0/go.mod h1:Iv2aJVtVSm/D22rFoX99cLG4q4uB7tppuCsulGe98k4= -github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= -github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= @@ -801,20 +801,16 @@ github.com/onflow/flow-ft/lib/go/templates v1.0.1 h1:FDYKAiGowABtoMNusLuRCILIZDt github.com/onflow/flow-ft/lib/go/templates v1.0.1/go.mod h1:uQ8XFqmMK2jxyBSVrmyuwdWjTEb+6zGjRYotfDJ5pAE= github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 h1:LzgHQI7A8rINyfzKEF6x2gsrzx7zGBQpmgdHJjJtQqM= github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9/go.mod h1:VkvpX4p4imUpPR+FhL0Qw7Qx32zQ/QOQRz2Vl2uu50Y= -github.com/onflow/flow-go-sdk v1.8.1 h1:BPp7p10RrpOdezQ3RJ+nheOqpalHlTB9bRocVkLsGNU= -github.com/onflow/flow-go-sdk v1.8.1/go.mod h1:w6bxCznDhJJCDybn1jCUAz3rEO4/7XY9EgWRFrj0zoo= -github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f h1:7l/WGE02V07jXveC0zjYCjHE651SeSXd1/6VVoNds5Q= -github.com/onflow/flow-go-sdk v1.8.2-0.20250916034424-f5bc339ee94f/go.mod h1:Gc09IwcvwaW4kqZ9xTaC0KahRxWApGeEMnWVnW8ZNPA= +github.com/onflow/flow-go-sdk v1.8.2 h1:Jkoh0LdH4kIADFdHoHK31qHcH0QnCkAL+ybjAkBEbqc= +github.com/onflow/flow-go-sdk v1.8.2/go.mod h1:/5g1t+xgk1nFXz8ifk8O3aT4DqLwq5p3k2BhiW4ZX+U= github.com/onflow/flow-nft/lib/go/contracts v1.2.4 h1:gWJgSSgIGo0qWOqr90+khQ69VoYF9vNlqzF+Yh6YYy4= github.com/onflow/flow-nft/lib/go/contracts v1.2.4/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= github.com/onflow/flow-nft/lib/go/templates v1.2.1/go.mod h1:W6hOWU0xltPqNpv9gQX8Pj8Jtf0OmRxc1XX2V0kzJaI= github.com/onflow/flow/protobuf/go/flow v0.4.12 h1:nMJHVuz2iRQnzEwvmruCaMrQvm/dfdWtbKroi3o/42M= github.com/onflow/flow/protobuf/go/flow v0.4.12/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= -github.com/onflow/flowkit/v2 v2.5.0 h1:Y5eFuFHem8a4gNaZl+47Jr7qyBFkU0X+opUVUD72CcE= -github.com/onflow/flowkit/v2 v2.5.0/go.mod h1:wfWK0O8VxdCbAREo1Snnagt1l9GuqFdmyAQXeymzpiY= -github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87 h1:qQFjm2aLCn7mtJuCfXOmn6D/502foT+SYwtL1bMT0Nc= -github.com/onflow/flowkit/v2 v2.5.1-0.20250916172151-d09544191c87/go.mod h1:lwN9h5GKD7p3GhXl4QqM0Ddez/0Ad3gWb16YPoOZ6iI= +github.com/onflow/flowkit/v2 v2.5.1 h1:02Y91zpwGDUhbGu+E4RVQ90ltaVcP6GLpNTBOEI5vaM= +github.com/onflow/flowkit/v2 v2.5.1/go.mod h1:59aJa3S+1MtDbb13wQF1igw7Nsvw5kQSUa0vBDGELmI= github.com/onflow/go-ethereum v1.15.10 h1:blZBeOLJDOVWqKuhkkMh6S2PKQAJvdgbvOL9ZNggFcU= github.com/onflow/go-ethereum v1.15.10/go.mod h1:t2nZJtwruVjA5u5yEK8InFzjImFLHrF7ak2bw3E4LDM= github.com/onflow/nft-storefront/lib/go/contracts v1.0.0 h1:sxyWLqGm/p4EKT6DUlQESDG1ZNMN9GjPCm1gTq7NGfc= @@ -1465,10 +1461,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= -google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 376a20a25..19a8689b8 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -75,16 +75,26 @@ func ApproveTransactionPrompt(tx *flow.Transaction, promptMsg string) bool { for i, e := range tx.PayloadSignatures { _, _ = fmt.Fprintf(writer, "\nPayload Signature %v:\n", i) - _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) - _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) - _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + _, _ = fmt.Fprintf(writer, " Address\t\t%s\n", e.Address) + _, _ = fmt.Fprintf(writer, " Signature\t\t%x\n", e.Signature) + _, _ = fmt.Fprintf(writer, " Key Index\t\t%d\n", e.KeyIndex) + if len(e.ExtensionData) > 0 { + _, _ = fmt.Fprintf(writer, " Extension Data\t%x\n", e.ExtensionData) + } else { + _, _ = fmt.Fprintf(writer, " Extension Data\t None\n") + } } for i, e := range tx.EnvelopeSignatures { _, _ = fmt.Fprintf(writer, "\nEnvelope Signature %v:\n", i) - _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) - _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) - _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + _, _ = fmt.Fprintf(writer, " Address\t\t%s\n", e.Address) + _, _ = fmt.Fprintf(writer, " Signature\t\t%x\n", e.Signature) + _, _ = fmt.Fprintf(writer, " Key Index\t\t%d\n", e.KeyIndex) + if len(e.ExtensionData) > 0 { + _, _ = fmt.Fprintf(writer, " Extension Data\t%x\n", e.ExtensionData) + } else { + _, _ = fmt.Fprintf(writer, " Extension Data\t None\n") + } } if tx.Script != nil { diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 54624408b..307677d4e 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -171,6 +171,9 @@ func (r *transactionResult) String() string { _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + if len(e.ExtensionData) > 0 { + _, _ = fmt.Fprintf(writer, " Extension Data\t%x\n", e.ExtensionData) + } } else { _, _ = fmt.Fprintf(writer, "\nPayload Signature %v: %s", i, e.Address) } @@ -182,6 +185,9 @@ func (r *transactionResult) String() string { _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + if len(e.ExtensionData) > 0 { + _, _ = fmt.Fprintf(writer, " Extension Data\t%x\n", e.ExtensionData) + } } else { _, _ = fmt.Fprintf(writer, "\nEnvelope Signature %v: %s", i, e.Address) } From 45f0bdd01a348cb01367412619cc5e3be4b0bee9 Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Wed, 17 Sep 2025 16:09:57 -0700 Subject: [PATCH 3/5] new add-sig subcommand --- go.mod | 2 +- go.sum | 4 + internal/transactions/add-sig.go | 194 ++++++++++++++++++++++++++ internal/transactions/transactions.go | 1 + 4 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 internal/transactions/add-sig.go diff --git a/go.mod b/go.mod index e9f106144..8824d9dbc 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/onflow/flow-emulator v1.7.0 github.com/onflow/flow-evm-gateway v1.3.0 github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 - github.com/onflow/flow-go-sdk v1.8.2 + github.com/onflow/flow-go-sdk v1.8.3-0.20250917204435-cd9d4cf5f6af github.com/onflow/flowkit/v2 v2.5.1 github.com/onflowser/flowser/v3 v3.2.1-0.20240131200229-7d4d22715f48 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c diff --git a/go.sum b/go.sum index a224368bb..92962a440 100644 --- a/go.sum +++ b/go.sum @@ -803,6 +803,10 @@ github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9 h1: github.com/onflow/flow-go v0.43.0-dev-pebble.1.0.20250910132853-12699a150fd9/go.mod h1:VkvpX4p4imUpPR+FhL0Qw7Qx32zQ/QOQRz2Vl2uu50Y= github.com/onflow/flow-go-sdk v1.8.2 h1:Jkoh0LdH4kIADFdHoHK31qHcH0QnCkAL+ybjAkBEbqc= github.com/onflow/flow-go-sdk v1.8.2/go.mod h1:/5g1t+xgk1nFXz8ifk8O3aT4DqLwq5p3k2BhiW4ZX+U= +github.com/onflow/flow-go-sdk v1.8.3-0.20250917001858-5aa1f787eb8e h1:A4EVQWNo8bTlGV7O1e7AzKJ4WXVOTPryY2SHsCqVR3I= +github.com/onflow/flow-go-sdk v1.8.3-0.20250917001858-5aa1f787eb8e/go.mod h1:/5g1t+xgk1nFXz8ifk8O3aT4DqLwq5p3k2BhiW4ZX+U= +github.com/onflow/flow-go-sdk v1.8.3-0.20250917204435-cd9d4cf5f6af h1:C7pJVDcTEFqm65oW27WgpRhONOvPu4lFFWx9kGZKLgg= +github.com/onflow/flow-go-sdk v1.8.3-0.20250917204435-cd9d4cf5f6af/go.mod h1:/5g1t+xgk1nFXz8ifk8O3aT4DqLwq5p3k2BhiW4ZX+U= github.com/onflow/flow-nft/lib/go/contracts v1.2.4 h1:gWJgSSgIGo0qWOqr90+khQ69VoYF9vNlqzF+Yh6YYy4= github.com/onflow/flow-nft/lib/go/contracts v1.2.4/go.mod h1:eZ9VMMNfCq0ho6kV25xJn1kXeCfxnkhj3MwF3ed08gY= github.com/onflow/flow-nft/lib/go/templates v1.2.1 h1:SAALMZPDw9Eb9p5kSLnmnFxjyig1MLiT4JUlLp0/bSE= diff --git a/internal/transactions/add-sig.go b/internal/transactions/add-sig.go new file mode 100644 index 000000000..3153b434e --- /dev/null +++ b/internal/transactions/add-sig.go @@ -0,0 +1,194 @@ +/* + * Flow CLI + * + * Copyright Flow Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package transactions + +import ( + "context" + "encoding/hex" + "fmt" + "math" + "sort" + "strconv" + "strings" + + "github.com/onflow/flow-cli/internal/prompt" + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go-sdk/crypto" + + "github.com/onflow/flowkit/v2/config" + "github.com/onflow/flowkit/v2/transactions" + + "github.com/onflow/flowkit/v2/accounts" + + "github.com/spf13/cobra" + + "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/output" + + "github.com/onflow/flow-cli/internal/command" +) + +type flagsAddSig struct { + Include []string `default:"" flag:"include" info:"Fields to include in the output. Valid values: signatures, code, payload."` + KeyIndex string `default:"0" flag:"key-index" info:"Account key index"` +} + +var addSigFlags = flagsAddSig{} + +var addSigCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "add-sig
", + Short: "Add signature to a prebuilt transaction", + Example: "flow transactions add-sig ./built.rlp 99fa...25b", + Args: cobra.ExactArgs(3), + }, + Flags: &addSigFlags, + RunS: addSig, +} + +func addSig( + args []string, + globalFlags command.GlobalFlags, + _ output.Logger, + flow flowkit.Services, + state *flowkit.State, +) (command.Result, error) { + var payload []byte + var err error + filename := args[0] + payload, err = state.ReadFile(filename) + + if err != nil { + return nil, fmt.Errorf("failed to read partial transaction from %s: %v", filename, err) + } + + address := flowsdk.HexToAddress(args[1]) + + sig, err := hex.DecodeString(strings.ReplaceAll(args[2], "0x", "")) + if err != nil { + return nil, fmt.Errorf("invalid message signature: %w", err) + } + + index, err := parseKeyIndex(addSigFlags.KeyIndex) + if err != nil { + return nil, err + } + + var signed *transactions.Transaction + var signers []*accounts.Account + tx, err := transactions.NewFromPayload(payload) + if err != nil { + return nil, err + } + + // validate all signers + signerAccount := &accounts.Account{ + Address: address, + Key: &dummyKey{index: index, signer: crypto.NewAddSignatureSigner(sig, nil)}, + } + + //payer signs last + sort.SliceStable(signers, func(i, j int) bool { + return signers[i].Address.String() != tx.FlowTransaction().Payer.Hex() + }) + + if !globalFlags.Yes && !prompt.ApproveTransactionForSigningPrompt(tx.FlowTransaction()) { + return nil, fmt.Errorf("transaction was not approved for signing") + } + + signed, err = flow.SignTransactionPayload(context.Background(), signerAccount, payload) + if err != nil { + return nil, err + } + + payload = []byte(hex.EncodeToString(signed.FlowTransaction().Encode())) + + return &transactionResult{ + tx: signed.FlowTransaction(), + include: addSigFlags.Include, + network: flow.Network().Name, + }, nil +} + +type dummyKey struct { + keyType config.KeyType + index uint32 + sigAlgo crypto.SignatureAlgorithm + hashAlgo crypto.HashAlgorithm + signer crypto.Signer +} + +var _ accounts.Key = &dummyKey{} + +func (a *dummyKey) Type() config.KeyType { + return a.keyType +} + +func (a *dummyKey) SigAlgo() crypto.SignatureAlgorithm { + if a.sigAlgo == crypto.UnknownSignatureAlgorithm { + return crypto.ECDSA_P256 // default value + } + return a.sigAlgo +} + +func (a *dummyKey) HashAlgo() crypto.HashAlgorithm { + if a.hashAlgo == crypto.UnknownHashAlgorithm { + return crypto.SHA3_256 // default value + } + return a.hashAlgo +} + +func (a *dummyKey) Index() uint32 { + return a.index // default to 0 +} + +func (a *dummyKey) Validate() error { + return nil +} +func (a *dummyKey) Signer(ctx context.Context) (crypto.Signer, error) { + return a.signer, nil +} +func (a *dummyKey) ToConfig() config.AccountKey { + return config.AccountKey{ + Type: a.keyType, + Index: a.index, + SigAlgo: a.sigAlgo, + HashAlgo: a.hashAlgo, + Mnemonic: "", + DerivationPath: "", + } +} +func (a *dummyKey) PrivateKey() (*crypto.PrivateKey, error) { + return nil, fmt.Errorf("This key type does not support private key retrieval") +} + +func parseKeyIndex(value string) (uint32, error) { + v, err := strconv.Atoi(value) + if err != nil { + return 0, fmt.Errorf("invalid index, must be a number") + } + if v < 0 { + return 0, fmt.Errorf("invalid index, must be positive") + } + if v > math.MaxUint32 { + return 0, fmt.Errorf("invalid index, must be less than %d", math.MaxUint32) + } + + return uint32(v), nil +} diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 307677d4e..5ed38c19d 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -47,6 +47,7 @@ func init() { getCommand.AddToParent(Cmd) sendCommand.AddToParent(Cmd) signCommand.AddToParent(Cmd) + addSigCommand.AddToParent(Cmd) buildCommand.AddToParent(Cmd) sendSignedCommand.AddToParent(Cmd) getSystemCommand.AddToParent(Cmd) From 227987ce6a910a25583957bda9c6f88f7e23a74d Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Wed, 17 Sep 2025 16:38:47 -0700 Subject: [PATCH 4/5] lint --- internal/transactions/add-sig.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/internal/transactions/add-sig.go b/internal/transactions/add-sig.go index 3153b434e..52aef2907 100644 --- a/internal/transactions/add-sig.go +++ b/internal/transactions/add-sig.go @@ -27,21 +27,18 @@ import ( "strconv" "strings" - "github.com/onflow/flow-cli/internal/prompt" flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" - - "github.com/onflow/flowkit/v2/config" - "github.com/onflow/flowkit/v2/transactions" - - "github.com/onflow/flowkit/v2/accounts" - "github.com/spf13/cobra" "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/accounts" + "github.com/onflow/flowkit/v2/config" "github.com/onflow/flowkit/v2/output" + "github.com/onflow/flowkit/v2/transactions" "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/internal/prompt" ) type flagsAddSig struct { @@ -117,8 +114,6 @@ func addSig( return nil, err } - payload = []byte(hex.EncodeToString(signed.FlowTransaction().Encode())) - return &transactionResult{ tx: signed.FlowTransaction(), include: addSigFlags.Include, From 5fabd328c298289f1aa174c4ae2f41040be34701 Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Wed, 17 Sep 2025 19:33:10 -0700 Subject: [PATCH 5/5] Add version where we overload sign func --- internal/transactions/add-sig.go | 189 -------------------------- internal/transactions/sign.go | 92 ++++++++++++- internal/transactions/transactions.go | 1 - 3 files changed, 91 insertions(+), 191 deletions(-) delete mode 100644 internal/transactions/add-sig.go diff --git a/internal/transactions/add-sig.go b/internal/transactions/add-sig.go deleted file mode 100644 index 52aef2907..000000000 --- a/internal/transactions/add-sig.go +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Flow CLI - * - * Copyright Flow Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package transactions - -import ( - "context" - "encoding/hex" - "fmt" - "math" - "sort" - "strconv" - "strings" - - flowsdk "github.com/onflow/flow-go-sdk" - "github.com/onflow/flow-go-sdk/crypto" - "github.com/spf13/cobra" - - "github.com/onflow/flowkit/v2" - "github.com/onflow/flowkit/v2/accounts" - "github.com/onflow/flowkit/v2/config" - "github.com/onflow/flowkit/v2/output" - "github.com/onflow/flowkit/v2/transactions" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/prompt" -) - -type flagsAddSig struct { - Include []string `default:"" flag:"include" info:"Fields to include in the output. Valid values: signatures, code, payload."` - KeyIndex string `default:"0" flag:"key-index" info:"Account key index"` -} - -var addSigFlags = flagsAddSig{} - -var addSigCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "add-sig
", - Short: "Add signature to a prebuilt transaction", - Example: "flow transactions add-sig ./built.rlp 99fa...25b", - Args: cobra.ExactArgs(3), - }, - Flags: &addSigFlags, - RunS: addSig, -} - -func addSig( - args []string, - globalFlags command.GlobalFlags, - _ output.Logger, - flow flowkit.Services, - state *flowkit.State, -) (command.Result, error) { - var payload []byte - var err error - filename := args[0] - payload, err = state.ReadFile(filename) - - if err != nil { - return nil, fmt.Errorf("failed to read partial transaction from %s: %v", filename, err) - } - - address := flowsdk.HexToAddress(args[1]) - - sig, err := hex.DecodeString(strings.ReplaceAll(args[2], "0x", "")) - if err != nil { - return nil, fmt.Errorf("invalid message signature: %w", err) - } - - index, err := parseKeyIndex(addSigFlags.KeyIndex) - if err != nil { - return nil, err - } - - var signed *transactions.Transaction - var signers []*accounts.Account - tx, err := transactions.NewFromPayload(payload) - if err != nil { - return nil, err - } - - // validate all signers - signerAccount := &accounts.Account{ - Address: address, - Key: &dummyKey{index: index, signer: crypto.NewAddSignatureSigner(sig, nil)}, - } - - //payer signs last - sort.SliceStable(signers, func(i, j int) bool { - return signers[i].Address.String() != tx.FlowTransaction().Payer.Hex() - }) - - if !globalFlags.Yes && !prompt.ApproveTransactionForSigningPrompt(tx.FlowTransaction()) { - return nil, fmt.Errorf("transaction was not approved for signing") - } - - signed, err = flow.SignTransactionPayload(context.Background(), signerAccount, payload) - if err != nil { - return nil, err - } - - return &transactionResult{ - tx: signed.FlowTransaction(), - include: addSigFlags.Include, - network: flow.Network().Name, - }, nil -} - -type dummyKey struct { - keyType config.KeyType - index uint32 - sigAlgo crypto.SignatureAlgorithm - hashAlgo crypto.HashAlgorithm - signer crypto.Signer -} - -var _ accounts.Key = &dummyKey{} - -func (a *dummyKey) Type() config.KeyType { - return a.keyType -} - -func (a *dummyKey) SigAlgo() crypto.SignatureAlgorithm { - if a.sigAlgo == crypto.UnknownSignatureAlgorithm { - return crypto.ECDSA_P256 // default value - } - return a.sigAlgo -} - -func (a *dummyKey) HashAlgo() crypto.HashAlgorithm { - if a.hashAlgo == crypto.UnknownHashAlgorithm { - return crypto.SHA3_256 // default value - } - return a.hashAlgo -} - -func (a *dummyKey) Index() uint32 { - return a.index // default to 0 -} - -func (a *dummyKey) Validate() error { - return nil -} -func (a *dummyKey) Signer(ctx context.Context) (crypto.Signer, error) { - return a.signer, nil -} -func (a *dummyKey) ToConfig() config.AccountKey { - return config.AccountKey{ - Type: a.keyType, - Index: a.index, - SigAlgo: a.sigAlgo, - HashAlgo: a.hashAlgo, - Mnemonic: "", - DerivationPath: "", - } -} -func (a *dummyKey) PrivateKey() (*crypto.PrivateKey, error) { - return nil, fmt.Errorf("This key type does not support private key retrieval") -} - -func parseKeyIndex(value string) (uint32, error) { - v, err := strconv.Atoi(value) - if err != nil { - return 0, fmt.Errorf("invalid index, must be a number") - } - if v < 0 { - return 0, fmt.Errorf("invalid index, must be positive") - } - if v > math.MaxUint32 { - return 0, fmt.Errorf("invalid index, must be less than %d", math.MaxUint32) - } - - return uint32(v), nil -} diff --git a/internal/transactions/sign.go b/internal/transactions/sign.go index 689e157ec..a918e5dad 100644 --- a/internal/transactions/sign.go +++ b/internal/transactions/sign.go @@ -24,11 +24,16 @@ import ( "encoding/hex" "fmt" "io" + "math" "net/http" "sort" + "strconv" + "strings" "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flow-go-sdk/crypto" + "github.com/onflow/flowkit/v2/config" "github.com/onflow/flowkit/v2/transactions" "github.com/onflow/flowkit/v2/accounts" @@ -46,6 +51,7 @@ type flagsSign struct { Signer []string `default:"emulator-account" flag:"signer" info:"name of a single or multiple comma-separated accounts used to sign"` Include []string `default:"" flag:"include" info:"Fields to include in the output. Valid values: signatures, code, payload."` FromRemoteUrl string `default:"" flag:"from-remote-url" info:"server URL where RLP can be fetched, signed RLP will be posted back to remote URL."` + RawSig []string `default:"" flag:"raw-sig" info:"Raw hex-encoded signature to add to the transaction, instead of signing with a private key from an account in the config."` } var signFlags = flagsSign{} @@ -101,12 +107,29 @@ func sign( return nil, err } + // Use raw signatures if provided, and if the number of signatures matches the number of signers + useRawSig := len(signFlags.RawSig) == len(signFlags.Signer) + // validate all signers - for _, signerName := range signFlags.Signer { + for i, signerName := range signFlags.Signer { signer, err := state.Accounts().ByName(signerName) if err != nil { return nil, fmt.Errorf("signer account: [%s] doesn't exists in configuration", signerName) } + if useRawSig { + sig, err := hex.DecodeString(strings.ReplaceAll(signFlags.RawSig[i], "0x", "")) + if err != nil { + return nil, fmt.Errorf("invalid message signature: %w", err) + } + // If a raw signature is provided, use a dummy key that returns the signature instead of signing + signer.Key = &sigAddKey{ + index: signer.Key.Index(), + signer: crypto.NewAddSignatureSigner(sig, nil), + sigAlgo: signer.Key.SigAlgo(), + hashAlgo: signer.Key.HashAlgo(), + keyType: signer.Key.Type(), + } + } signers = append(signers, signer) } @@ -181,3 +204,70 @@ func postRLPTransaction(rlpUrl string, tx *flowsdk.Transaction) error { return nil } + +type sigAddKey struct { + keyType config.KeyType + index uint32 + sigAlgo crypto.SignatureAlgorithm + hashAlgo crypto.HashAlgorithm + signer crypto.Signer +} + +var _ accounts.Key = &sigAddKey{} + +func (a *sigAddKey) Type() config.KeyType { + return a.keyType +} + +func (a *sigAddKey) SigAlgo() crypto.SignatureAlgorithm { + if a.sigAlgo == crypto.UnknownSignatureAlgorithm { + return crypto.ECDSA_P256 // default value + } + return a.sigAlgo +} + +func (a *sigAddKey) HashAlgo() crypto.HashAlgorithm { + if a.hashAlgo == crypto.UnknownHashAlgorithm { + return crypto.SHA3_256 // default value + } + return a.hashAlgo +} + +func (a *sigAddKey) Index() uint32 { + return a.index // default to 0 +} + +func (a *sigAddKey) Validate() error { + return nil +} +func (a *sigAddKey) Signer(ctx context.Context) (crypto.Signer, error) { + return a.signer, nil +} +func (a *sigAddKey) ToConfig() config.AccountKey { + return config.AccountKey{ + Type: a.keyType, + Index: a.index, + SigAlgo: a.sigAlgo, + HashAlgo: a.hashAlgo, + Mnemonic: "", + DerivationPath: "", + } +} +func (a *sigAddKey) PrivateKey() (*crypto.PrivateKey, error) { + return nil, fmt.Errorf("This key type does not support private key retrieval") +} + +func parseKeyIndex(value string) (uint32, error) { + v, err := strconv.Atoi(value) + if err != nil { + return 0, fmt.Errorf("invalid index, must be a number") + } + if v < 0 { + return 0, fmt.Errorf("invalid index, must be positive") + } + if v > math.MaxUint32 { + return 0, fmt.Errorf("invalid index, must be less than %d", math.MaxUint32) + } + + return uint32(v), nil +} diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 5ed38c19d..307677d4e 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -47,7 +47,6 @@ func init() { getCommand.AddToParent(Cmd) sendCommand.AddToParent(Cmd) signCommand.AddToParent(Cmd) - addSigCommand.AddToParent(Cmd) buildCommand.AddToParent(Cmd) sendSignedCommand.AddToParent(Cmd) getSystemCommand.AddToParent(Cmd)