Offline Transaction Signing with the Koii CLI
It is sometimes necessary to keep signing keys offline, which in turn requires offline signing of transactions. Below you will find the instructions detailing how to sign a transaction offline and submit it online.
Offline Signing Commands
These commands in the Koii CLI support offline signing:
create-stake-account
create-stake-account-checked
deactivate-stake
delegate-stake
split-stake
stake-authorize
stake-authorize-checked
stake-set-lockup
stake-set-lockup-checked
transfer
withdraw-stake
create-vote-account
vote-authorize-voter
vote-authorize-voter-checked
vote-authorize-withdrawer
vote-authorize-withdrawer-checked
vote-update-commission
vote-update-validator
withdraw-from-vote-account
Signing Transactions Offline
To sign a transaction offline, you will need to pass the --sign-only
and --blockhash <BASE58_HASH>
arguments on the command line
--sign_only
prints the public key and signature pairs to stdout rather than submitting the transaction, and --blockhash <BASE58_HASH>
allows you to specify the value for the recent_blockhash
field in your transaction, eliminating the need to connect to the network to get a recent blockhash.
Example Signing Command
koii transfer --sign-only --blockhash F3rXs1PnTq1Ht4B6d8YJkZmNV72MWTCLFkp6JdUoZ5RN recipient-keypair.json 10
Example Signing Output
Blockhash: F3rXs1PnTq1Ht4B6d8YJkZmNV72MWTCLFkp6JdUoZ5RN
Signers (Pubkey=Signature): G9nV8XL7P7BkGXPZWm69DZGqmhqVDBZACkZhWyqJvU5G=A9nr12dXHm3TYW1vTLk1w3LX4UXPRkQk9F2LK68Fb1X9vR84UzFEtVmHbL6jVNCb1h5RLWUVhW8XzFzkCvXZCZZYkpXH
{"blockhash":"F3rXs1PnTq1Ht4B6d8YJkZmNV72MWTCLFkp6JdUoZ5RN","signers": ["G9nV8XL7P7BkGXPZWm69DZGqmhqVDBZACkZhWyqJvU5G=A9nr12dXHm3TYW1vTLk1w3LX4UXPRkQk9F2LK68Fb1X9vR84UzFEtVmHbL6jVNCb1h5RLWUVhW8XzFzkCvXZCZZYkpXH"]}'
Submitting Transactions to the Network
To submit the transaction you just signed offline, pass the --blockhash <BASE58_HASH>
and --signer <BASE58_PUBKEY>=<BASE58_SIGNATURE>
arguments. These will be the same values you received as output from the offline signing.
Example Transfer Command
koii transfer --blockhash F3rXs1PnTq1Ht4B6d8YJkZmNV72MWTCLFkp6JdUoZ5RN \
--signer G9nV8XL7P7BkGXPZWm69DZGqmhqVDBZACkZhWyqJvU5G=A9nr12dXHm3TYW1vTLk1w3LX4UXPRkQk9F2LK68Fb1X9vR84UzFEtVmHbL6jVNCb1h5RLWUVhW8XzFzkCvXZCZZYkpXH \
recipient-keypair.json 10
Example Transfer Output
A9nr12dXHm3TYW1vTLk1w3LX4UXPRkQk9F2LK68Fb1X9vR84UzFEtVmHbL6jVNCb1h5RLWUVhW8XzFzkCvXZCZZYkpXH
Multi-Session Offline Signing
It may sometimes be necessary to sign a transaction over multiple sessions. To do so, pass the absent signer's public key for each missing role.
Example First Signing Command
koii transfer H1zfq3PuH5yQ9G5FtR6FgksYbAbdGfB2Tr9kDcV4p99x 20 \
--blockhash EXuVqWPNtTMD2q7Jv1Cz1PgLWPLBhVCvfxKPj89BMJbX \
--sign-only --keypair fee_payer.json \
--from J6wGtZ6Xr7sL1pLf8j8f7Sh8nK7JhMwF2bWLFPs43MhW
Example First Signing Output
Blockhash: EXuVqWPNtTMD2q7Jv1Cz1PgLWPLBhVCvfxKPj89BMJbX
(Pubkey=Signature): J6wGtZ6Xr7sL1pLf8j8f7Sh8nK7JhMwF2bWLFPs43MhW=C8kWL5V8dP2ZTQLM4Y9WVY8MRLV4ZYFZ6FVRFT8JLXLkJRFZ9FTkWLP3FNVRL9FTWLXT5XVzTLZWLkR8kLMVR8kZF8XM
Absent Signers (Pubkey):
J6wGtZ6Xr7sL1pLf8j8f7Sh8nK7JhMwF2bWLFPs43MhW
Example Second Signing Command
koii transfer H1zfq3PuH5yQ9G5FtR6FgksYbAbdGfB2Tr9kDcV4p99x 20 \
--blockhash EXuVqWPNtTMD2q7Jv1Cz1PgLWPLBhVCvfxKPj89BMJbX \
--sign-only --keypair from.json \
--fee-payer F1Xh8LdGqVq9pYJQ1XfB7Mv8KdM4F2P5XpL9VrJWVpkA
Example Second Signing Output
Blockhash: EXuVqWPNtTMD2q7Jv1Cz1PgLWPLBhVCvfxKPj89BMJbX
(Pubkey=Signature): F1Xh8LdGqVq9pYJQ1XfB7Mv8KdM4F2P5XpL9VrJWVpkA=B1pXTqZ8XmVRkNL2Y6YFzVmLZ2VrWzRf8kFkLVZyG68c7N4F6TkVb9Zm6NRXXfFzLfLz9XLTNvMFPz8TkJLWP8LFRkx
Absent Signers (Pubkey):
H1zfq3PuH5yQ9G5FtR6FgksYbAbdGfB2Tr9kDcV4p99x
Example Multi Signature Transfer Command
koii transfer H1zfq3PuH5yQ9G5FtR6FgksYbAbdGfB2Tr9kDcV4p99x 20 \
--blockhash 7ALDjLv56a8f6sH6upAZALQKkXyjAwwENH9GomyM8Dbc --from J6wGtZ6Xr7sL1pLf8j8f7Sh8nK7JhMwF2bWLFPs43MhW \
--signer J6wGtZ6Xr7sL1pLf8j8f7Sh8nK7JhMwF2bWLFPs43MhW=C8kWL5V8dP2ZTQLM4Y9WVY8MRLV4ZYFZ6FVRFT8JLXLkJRFZ9FTkWLP3FNVRL9FTWLXT5XVzTLZWLkR8kLMVR8kZF8XM \
--fee-payer F1Xh8LdGqVq9pYJQ1XfB7Mv8KdM4F2P5XpL9VrJWVpkA \
--signer F1Xh8LdGqVq9pYJQ1XfB7Mv8KdM4F2P5XpL9VrJWVpkA=B1pXTqZ8XmVRkNL2Y6YFzVmLZ2VrWzRf8kFkLVZyG68c7N4F6TkVb9Zm6NRXXfFzLfLz9XLTNvMFPz8TkJLWP8LFRkx
Example Multi Signature Transfer Output
B1pXTqZ8XmVRkNL2Y6YFzVmLZ2VrWzRf8kFkLVZyG68c7N4F6TkVb9Zm6NRXXfFzLfLz9XLTNvMFPz8TkJLWP8LFRkx
Increasing Signing Time
Signing time is limited to within a number of slots from the recent_blockhash
. If you need more time, you can use a Durable Transaction Nonce.